package org.summer.lawyer.domain.vo.paytransfer;

import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.binarywang.wxpay.bean.notify.WxPayTransferBatchesNotifyV3Result;
import io.github.linpeilie.annotations.AutoMapper;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.summer.lawyer.constant.enums.PayTransferStatus;
import org.summer.lawyer.domain.PayTransfer;

import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;



/**
 * 转账单视图对象 pay_transfer
 *
 * @author summer
 * @date 2024-06-22
 */
@Schema(title ="转账单视图对象 pay_transfer", description = "转账单视图对象 pay_transfer")
@Data
@AutoMapper(target = PayTransfer.class)
public class PayTransferVo implements Serializable{

    @Serial
    private static final long serialVersionUID = 1L;

    /**
     * 主键ID
     */
    @Schema(title = "id", type = "Long", description = "主键ID")
    private Long id;

    /**
     * 转账订单ID
     */
    @Schema(title = "transferNo", type = "String", description = "转账订单ID")
    private String transferNo;

    /**
     * 转账批次单号
     */
    @Schema(title = "transferBatchNo", type = "String", description = "转账批次单号")
    private String transferBatchNo;

    /**
     * 支付应用ID
     */
    @Schema(title = "appId", type = "Long", description = "支付应用ID")
    private Long appId;

    /**
     * 微信appid
     */
    @Schema(title = "wxAppId", type = "String", description = "微信appid")
    private String wxAppId;

    /**
     * 商户号
     */
    @Schema(title = "mchNo", type = "String", description = "商户号")
    private String mchNo;

    /**
     * 商户名称
     */
    @Schema(title = "mchName", type = "String", description = "商户名称")
    private String mchName;

    /**
     * 通道ID
     */
    @Schema(title = "channelId", type = "Long", description = "通道ID")
    private Long channelId;

    /**
     * 通道编码
     */
    @Schema(title = "channelCode", type = "String", description = "通道编码")
    private String channelCode;

    /**
     * 提现记录编号
     */
    @Schema(title = "withdrawNumber", type = "String", description = "提现记录编号")
    private String withdrawNumber;

    /**
     * 用户ID
     */
    @Schema(title = "userId", type = "Long", description = "用户ID")
    private Long userId;

    /**
     * 用户openId
     */
    @Schema(title = "openId", type = "String", description = "用户openId")
    private String openId;

    /**
     * 收款方姓名
     */
    @Schema(title = "userName", type = "String", description = "收款方姓名")
    private String userName;

    /**
     * 转账说明
     */
    @Schema(title = "transferRemark", type = "String", description = "转账说明")
    private String transferRemark;

    /**
     * 第三方交易号
     */
    @Schema(title = "tradeNo", type = "String", description = "第三方交易号")
    private String tradeNo;

    /**
     * 付款方式
     */
    @Schema(title = "payWay", type = "String", description = "付款方式")
    private String payWay;

    /**
     * 转账状态
     */
    @Schema(title = "transferStatus", type = "Integer", description = "转账状态")
    private Integer transferStatus;

    /**
     * 转账时间
     */
    @Schema(title = "transferTime", type = "Date", description = "转账时间")
    private Date transferTime;

    /**
     * 回调状态（1成功，2失败）
     */
    @Schema(title = "returnStatus", type = "Integer", description = "回调状态（1成功，2失败）")
    private Integer returnStatus;

    /**
     * 支付金额（单位分）
     */
    @Schema(title = "amount", type = "Long", description = "支付金额（单位分）")
    private Long amount;

    /**
     * 第三方返回的错误码
     */
    @Schema(title = "resultCode", type = "String", description = "第三方返回的错误码")
    private String resultCode;

    /**
     * 第三方返回的错误信息
     */
    @Schema(title = "resultMsg", type = "String", description = "第三方返回的错误信息")
    private String resultMsg;

    /**
     * 提交的信息
     */
    @Schema(title = "postJson", type = "String", description = "提交的信息")
    private String postJson;

    /**
     * 回调的信息
     */
    @Schema(title = "returnJson", type = "String", description = "回调的信息")
    private String returnJson;

    /**
     * 回调时间
     */
    @Schema(title = "returnTime", type = "Date", description = "回调时间")
    private Date returnTime;

    /**
     * 回调地址
     */
    @Schema(title = "notifyUrl", type = "String", description = "回调地址")
    private String notifyUrl;

    /**
     * 成功时间
     */
    @Schema(title = "successTime", type = "Date", description = "成功时间")
    private LocalDateTime successTime;


    /**
     * 原始的异步通知结果
     */
    @JsonIgnore
    @Schema(title = "rawData", type = "Object", description = "原始的异步通知结果")
    private Object rawData;

    /**
     *转账总笔数
     */
    private Integer totalNum;

    /**
     * 转账总金额，单位为“分”
     */
    private Integer totalAmount;

    /**
     * 转账成功金额,单位为“分”
     */
    private Integer successAmount;

    /**
     * 转账成功笔数
     */
    private Integer successNum;

    /**
     * 转账失败的金额，单位为“分”
     */
    private Integer failAmount;

    /**
     * 转账失败的笔数
     */
    private Integer failNum;



    public static PayTransferVo successOf(String transferNo, String transferBatchNo, String tradeNo,  LocalDateTime successTime, Object rawData){
        PayTransferVo payTransferVo = new PayTransferVo();
        payTransferVo.setTransferStatus(PayTransferStatus.SUCCESS.getCode());
        payTransferVo.setTransferNo(transferNo);
        payTransferVo.setTransferBatchNo(transferBatchNo);
        payTransferVo.setTradeNo(tradeNo);
        payTransferVo.setSuccessTime(successTime);
        payTransferVo.setRawData(rawData);
        payTransferVo.setReturnJson(JSONUtil.toJsonStr(rawData));
        return payTransferVo;
    }

    public static PayTransferVo acceptedOf(String transferNo,String transferBatchNo, String tradeNo,  LocalDateTime successTime, Object rawData){
        PayTransferVo payTransferVo = new PayTransferVo();
        payTransferVo.setTransferStatus(PayTransferStatus.ACCEPTED.getCode());
        payTransferVo.setTransferNo(transferNo);
        payTransferVo.setTransferBatchNo(transferBatchNo);
        payTransferVo.setTradeNo(tradeNo);
        payTransferVo.setSuccessTime(successTime);
        payTransferVo.setRawData(rawData);
        payTransferVo.setReturnJson(JSONUtil.toJsonStr(rawData));
        return payTransferVo;
    }

    public static PayTransferVo processingOf(String transferNo,String transferBatchNo, String tradeNo,  LocalDateTime successTime, Object rawData){
        PayTransferVo payTransferVo = new PayTransferVo();
        payTransferVo.setTransferStatus(PayTransferStatus.PROCESSING.getCode());
        payTransferVo.setTransferNo(transferNo);
        payTransferVo.setTransferBatchNo(transferBatchNo);
        payTransferVo.setTradeNo(tradeNo);
        payTransferVo.setSuccessTime(successTime);
        payTransferVo.setRawData(rawData);
        payTransferVo.setReturnJson(JSONUtil.toJsonStr(rawData));
        return payTransferVo;
    }

    public static PayTransferVo failureOf(String transferBatchNo, String tradeNo, Object rawData){
        PayTransferVo payTransferVo = new PayTransferVo();
        payTransferVo.setTransferStatus(PayTransferStatus.FAIL.getCode());
       // payTransferVo.setTransferNo(transferNo);
        payTransferVo.setTransferBatchNo(transferBatchNo);
        payTransferVo.setTradeNo(tradeNo);
        payTransferVo.setRawData(rawData);
        payTransferVo.setReturnJson(JSONUtil.toJsonStr(rawData));
        return payTransferVo;
    }

    public static PayTransferVo failureOf(String transferNo,String transferBatchNo, String tradeNo,  LocalDateTime successTime, Object rawData){
        WxPayTransferBatchesNotifyV3Result.DecryptNotifyResult result = (WxPayTransferBatchesNotifyV3Result.DecryptNotifyResult)rawData;
        PayTransferVo payTransferVo = new PayTransferVo();
        payTransferVo.setTransferStatus(PayTransferStatus.FAIL.getCode());
        payTransferVo.setTransferNo(transferNo);
        payTransferVo.setTransferBatchNo(transferBatchNo);
        payTransferVo.setTradeNo(tradeNo);
        payTransferVo.setRawData(rawData);
        payTransferVo.setReturnJson(JSONUtil.toJsonStr(rawData));
        payTransferVo.setResultMsg(result.getCloseReason());
        payTransferVo.setSuccessAmount(result.getSuccessAmount());
        payTransferVo.setTotalAmount(result.getTotalAmount());
        payTransferVo.setTotalNum(result.getTotalNum());
        payTransferVo.setFailAmount(result.getFailAmount());
        payTransferVo.setFailNum(result.getFailNum());
        return payTransferVo;
    }

    public static PayTransferVo of(Integer transferStatus,String transferNo,String transferBatchNo,String tradeNo, LocalDateTime successTime, Object rawData){
        PayTransferVo payTransferVo = new PayTransferVo();
        payTransferVo.setTransferStatus(transferStatus);
        payTransferVo.setTransferNo(transferNo);
        payTransferVo.setTransferBatchNo(transferBatchNo);
        payTransferVo.setTradeNo(tradeNo);
        payTransferVo.setSuccessTime(successTime);
        payTransferVo.setRawData(rawData);
        payTransferVo.setReturnJson(JSONUtil.toJsonStr(rawData));
        return payTransferVo;
    }

}
